package gdac

import (
	"database/sql/driver"
	"fmt"
)

type DacDBConn struct {
	daclib     *DacLib
	dacConn    uintptr
	dsn        string
	coinitflag bool
}

func NewDacDBConn(dsn string, daclib *DacLib) *DacDBConn {
	rval := &DacDBConn{dsn: dsn, daclib: daclib}
	return rval
}

func (c *DacDBConn) open() error {
	c.coinitflag = c.daclib.CoInitialize()
	c.dacConn = c.daclib.NewDACConn(c.dsn)
	if c.dacConn == 0 {
		return fmt.Errorf("Dac Driver load exception, DSN is right?")
	}
	return nil
}

func (c *DacDBConn) Begin() (driver.Tx, error) {
	rval := &DacDBDriverTx{dacConn: c.dacConn, daclib: c.daclib}
	err := rval.Begin()
	if err != nil {
		return nil, err
	}
	return rval, nil
}

func (c *DacDBConn) Prepare(query string) (driver.Stmt, error) {
	if c.dacConn == 0 {
		c.dacConn = c.daclib.NewDACConn(c.dsn)
	}
	rval := &DacStmt{dacconn: c.dacConn, daclib: c.daclib}
	rval.prepareCmdText(query)
	return rval, nil
}

func (c *DacDBConn) Close() error {
	if c.dacConn == 0 {
		return nil
	}
	c.daclib.CloseConn(c.dacConn)
	c.dacConn = 0
	if c.coinitflag {
		// 改用CoInitalizeEx(nil, COINIT_MULTITHREADED)
		c.daclib.CoUninitialize()
	}
	return nil
}
